package net.sql.config;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.dom4j.Element;

import net.dotool.MD5;
import net.dotool.StringTools;
import net.sql.i.ErrorListener;
import net.sql.i.IPrintError;
import net.sql.i.ISqlListener;
import net.sql.i.SqlListenerAfter;

/**
 * 
 * @author 李岩飞
 * @email eliyanfei@126.com 2017年12月25日 下午3:54:46
 *
 */
public class SQLConfig extends AbstractXmlParser {
	private static SQLConfig sqlConfig = null;
	public Map<String, SQLBean> sqlMap = new HashMap<String, SQLBean>();
	public static int INDEX = 0;
	private List<ISqlListener> listener = new ArrayList<ISqlListener>();
	public Map<String, SqlMonitor> monitorMap = new HashMap<String, SqlMonitor>();
	public int count = 0;

	/**
	 * 初始化
	 */
	public static void initSqlConfig(String path) {
		if (sqlConfig == null) {
			sqlConfig = new SQLConfig(path);
		}
	}

	/**
	 * 添加监听器
	 */
	public void addListener(ISqlListener sqlListener) {
		listener.add(sqlListener);
	}

	/**
	 * 获取实例
	 */
	public static SQLConfig getSqlConfig() {
		return sqlConfig;
	}

	private SQLConfig(String path) {
		initXml(path, "sqls", true);
	}

	/**
	 * 加入SQL监控
	 */
	public void addSqlMonitor() {
		listener.add(new SqlListenerAfter());
	}

	protected ErrorListener errorLis = null;

	public void addErrorMonitor(IPrintError printError) {
		errorLis = new ErrorListener(printError);
		listener.add(errorLis);
	}

	public void printError(Throwable e, String sql) {
		if (errorLis != null) {
			errorLis.printError(e, sql);
		}
	}

	/**
	 * 获取SqlBean对象
	 */
	public SQLBean getSQL(String id) {
		count++;
		return sqlMap.get(id);
	}

	@Override
	protected void parser(String fileName, Element rootEle) {
		try {
			Element root = rootEle.element("sqls");
			List<Element> eles = root.elements();

			String source = StringTools.trimNull(root.attributeValue("source"), "");
			String project = StringTools.trimNull(root.attributeValue("project"), "");
			String namespace = StringTools.trimNull(root.attributeValue("namespace"), "");
			String dbname = StringTools.trimNull(root.attributeValue("dbname"), "");
			for (Element ele : eles) {
				try {
					SQLBean bean = new SQLBean(project, namespace, source, dbname, ele);
					sqlMap.put(bean.getId(), bean);
				} catch (Exception e) {
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
			printError(e, "");
		}
	}

	public List<ISqlListener> getListener() {
		return listener;
	}

	/**
	 * 监听变化
	 */
	public void listener(SQLBean sqlBean, String hash, String sql, long useTime) {
		try {
			hash = MD5.getHashString(hash);
			SqlMonitor monitor = this.monitorMap.get(hash);
			if (monitor == null) {
				monitor = new SqlMonitor();
				monitor.setSqlId(sqlBean.getId());
				monitor.setSqls(sql);
				this.monitorMap.put(hash, monitor);
			}
			monitor.monitor(useTime);
		} catch (Exception e) {
		}
	}
}
